package com.happyfarmhelper.ctrl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.MasonTagTypes;
import net.htmlparser.jericho.MicrosoftTagTypes;
import net.htmlparser.jericho.Source;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import com.happyfarmhelper.utils.CommUtils;
import com.happyfarmhelper.vo.FarmlandStatus;
import com.happyfarmhelper.vo.Seed;
import com.happyfarmhelper.vo.User;

public class HappyCtrl {
	private final String RENREN_LOGIN_URL = "http://www.renren.com/PLogin.do";
	private final String HAPPYFARM_LOGIN_URL = "http://apps.renren.com/happyfarm";
	
	private Log log = LogFactory.getLog(HappyCtrl.class);
	private static HappyCtrl instance= new HappyCtrl();
	
	public HappyCtrl() {
		
	}
	
	public static HappyCtrl getInstance() {
        return instance;
    }
	/**
	 * 登录人人网
	 * 
	 * @param httpClient
	 * @param httpGet
	 * @param httpPost
	 * @param emailStr
	 * @param pwdStr
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public boolean loginToRenren(HttpClient httpClient, HttpGet httpGet, HttpPost httpPost, String emailStr, String pwdStr) throws ClientProtocolException, IOException {
		httpPost= new HttpPost(RENREN_LOGIN_URL);
		httpGet = new HttpGet();
		httpPost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpPost.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("email", emailStr));
		nvPairList.add(new BasicNameValuePair("password", pwdStr));
		nvPairList.add(new BasicNameValuePair("autoLogin", "true"));
		nvPairList.add(new BasicNameValuePair("origURL", "http://www.renren.com/Home.do"));
		nvPairList.add(new BasicNameValuePair("domain", "renren.com"));

		httpPost.setEntity(new UrlEncodedFormEntity(nvPairList, HTTP.UTF_8));
	
		HttpResponse response = httpClient.execute(httpPost);
		int statusCode = response.getStatusLine().getStatusCode();
		httpPost.abort();
		if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
			String location = response.getFirstHeader("Location").getValue();
			log.info("Location==" + location);
			if(location != null || !"".equals(location)){
				httpGet = new HttpGet(location);
				httpGet.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
				httpGet.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
				httpGet.getParams().setParameter("http.protocol.single-cookie-header", true);
				response = httpClient.execute(httpGet);
				httpGet.abort();
				log.info("Login Success!");
			} else {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 登录开心农场
	 * 
	 * @param httpClient
	 * @param httpGet
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public Map<String, Object> loginToHappyfarm(HttpClient httpClient, HttpGet httpGet) throws ClientProtocolException, IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		httpGet = new HttpGet(HAPPYFARM_LOGIN_URL);
		httpGet.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpGet.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		httpGet.getParams().setParameter("http.protocol.single-cookie-header", true);
		HttpResponse response = httpClient.execute(httpGet);
		int statusCode = response.getStatusLine().getStatusCode();
		if(statusCode != HttpStatus.SC_OK) {
			log.error("Login Error------" + response.getStatusLine());
			return null;
		}
		MicrosoftTagTypes.register();
		MasonTagTypes.register();
		Source source=new Source(response.getEntity().getContent());
		source.getAllElements(HTMLElementName.IFRAME);
		String src = "";
		for(Element element : source.getAllElements(HTMLElementName.IFRAME)){
			if("iframe_canvas".equals(element.getAttributeValue("id"))){
				src = element.getAttributeValue("src");
			}
		}
		log.info("src==" + src);
		
		httpGet.abort();
		
		httpGet = new HttpGet(src);
		httpGet.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpGet.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		httpGet.getParams().setParameter("http.protocol.single-cookie-header", true);
		
		response = httpClient.execute(httpGet);
		httpGet.abort();
		
		String farmtime = String.valueOf(Calendar.getInstance().getTimeInMillis()).substring(0, 10);
		String farmkey = CommUtils.getMD5Str(farmtime + "15l3h4kh");
		String farmURL = "http://xn.hf.fminutes.com/api.php?mod=user&act=run&farmKey=" + farmkey + "&farmTime=" + farmtime + "&inuId=";
		log.info("farmURL == " + farmURL);
		
		httpGet = new HttpGet(farmURL);
		httpGet.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpGet.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		httpGet.getParams().setParameter("http.protocol.single-cookie-header", true);
		
		response = httpClient.execute(httpGet);
		
		map = CommUtils.getFarmlandStatusFromJsonSting(response.getEntity().getContent());			
		
		return map;
	}
	
	/**
	 * 获取朋友
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public List<User> getFriends(HttpClient httpClient, HttpPost httpPost) throws ClientProtocolException, IOException {
		List<User> friendsList = new ArrayList<User>();
		double farmTime = Math.ceil(Calendar.getInstance().getTimeInMillis() / 1000);
        String farmKey = CommUtils.getMD5Str(farmTime + "15l3h4kh");
        String url = "http://xn.hf.fminutes.com/api.php?mod=friend&farmKey=" + farmKey + "&farmTime=" + farmTime + "&inuId=";
        log.info(url);
        httpPost = new HttpPost(url);
        
        httpPost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpPost.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("refresh", "true"));

		httpPost.setEntity(new UrlEncodedFormEntity(nvPairList, HTTP.UTF_8));
		HttpResponse response = httpClient.execute(httpPost);
		friendsList = CommUtils.getFriendsFromJsonString(response.getEntity().getContent());
		httpPost.abort();

		return friendsList;
	}
	
	/**
	 * 获取种子信息
	 * @param httpClient
	 * @param httpPost
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public Map<String, Seed> getSeedInfo(HttpClient httpClient, HttpPost httpPost) throws ClientProtocolException, IOException {
		Map<String, Seed> seedsMap = new HashMap<String, Seed>();
		
		double farmTime = Math.ceil(Calendar.getInstance().getTimeInMillis() / 1000);
        String farmKey = CommUtils.getMD5Str(farmTime + "15l3h4kh");
        String url = "http://xn.hf.fminutes.com/api.php?mod=shop&act=getShopInfo&type=1&farmKey=" + farmKey + "&farmTime=" + farmTime + "&inuId=";
        
        httpPost = new HttpPost(url);
        
        httpPost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpPost.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		
		HttpResponse response = httpClient.execute(httpPost);
		seedsMap = CommUtils.getSeedsMapFromJsonString(response.getEntity().getContent());
		httpPost.abort();
		
		return seedsMap;
	}
	/**
	 * 刷新画面
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public List<FarmlandStatus> refresh(HttpClient httpClient, HttpPost httpPost, String userId) throws ClientProtocolException, IOException {
		List<FarmlandStatus> farmlandStatusList = new ArrayList<FarmlandStatus>();
		double farmTime = Math.ceil(Calendar.getInstance().getTimeInMillis() / 1000);
        String farmKey = CommUtils.getMD5Str(farmTime + "15l3h4kh");
        String url = "http://xn.hf.fminutes.com/api.php?mod=user&act=run&flag=1&farmKey=" + farmKey + "&farmTime=" + farmTime + "&inuId=";
        
        httpPost = new HttpPost(url);
        
        httpPost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpPost.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("ownerId", userId));

		httpPost.setEntity(new UrlEncodedFormEntity(nvPairList, HTTP.UTF_8));
		HttpResponse response = httpClient.execute(httpPost);
		Map<String,Object> map = CommUtils.getFarmlandStatusFromJsonSting(response.getEntity().getContent());
		farmlandStatusList = (List<FarmlandStatus>)map.get("farmlandStatusList");
		httpPost.abort();
		
		return farmlandStatusList;
	}
	
	/**
	 * 共用方法,处理POST请求
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param preUrl
	 * @param nvPairList
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private String post(HttpClient httpClient, HttpPost httpPost, String preUrl, List<NameValuePair> nvPairList) throws ClientProtocolException, IOException{
		String msg = "";
		double farmTime = Math.ceil(Calendar.getInstance().getTimeInMillis() / 1000);
        String farmKey = CommUtils.getMD5Str(farmTime + "15l3h4kh");
        String url = preUrl + farmKey + "&farmTime=" + farmTime + "&inuId=";
        
        httpPost = new HttpPost(url);
        
        httpPost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpPost.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
        
		httpPost.setEntity(new UrlEncodedFormEntity(nvPairList, HTTP.UTF_8));
		HttpResponse response = httpClient.execute(httpPost);
		msg = CommUtils.getMsgFromJsonString(response.getEntity().getContent());
		httpPost.abort();
		
		return msg;
	}
	
	/**
	 * 除草
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param weedQuantity
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String clearWeed(HttpClient httpClient,HttpPost httpPost, String userId, int weedQuantity, int place) throws ClientProtocolException, IOException {
		StringBuffer msg = new StringBuffer();
		String preUrl = "http://xn.hf.fminutes.com/api.php?mod=farmlandstatus&act=clearWeed&farmKey=";
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		for (int i = weedQuantity; i > 0; i--) {
			msg.append(post(httpClient, httpPost, preUrl, nvPairList) + "\n");
		}
		return msg.toString();
	}
	
	/**
	 * 杀虫
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param quantityOfWeed
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String spraying(HttpClient httpClient, HttpPost httpPost, String userId, int quantityOfWeed, int place) throws ClientProtocolException, IOException {
		StringBuffer msg = new StringBuffer();
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("tId", "0"));
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		String preUrl = "http://xn.hf.fminutes.com/api.php?mod=farmlandstatus&act=spraying&farmKey=";
		for(int i = quantityOfWeed; i > 0; i--) {
			msg.append(post(httpClient, httpPost, preUrl, nvPairList) + "\n");
		}
		return msg.toString();
	}
	
	/**
	 * 浇水
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String water(HttpClient httpClient, HttpPost httpPost, String userId, int place) throws ClientProtocolException, IOException {
		String preUrl = "http://xn.hf.fminutes.com/api.php?mod=farmlandstatus&act=water&farmKey=";
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		
		return post(httpClient, httpPost, preUrl, nvPairList);
	}
	
	/**
	 * 施肥
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String fertilize(HttpClient httpClient, HttpPost httpPost, String userId, int place) throws ClientProtocolException, IOException {
		String preUrl = "http://xn.hf.fminutes.com/api.php?mod=farmlandstatus&act=fertilize&farmKey=";
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		nvPairList.add(new BasicNameValuePair("tId", "1"));
		
		return post(httpClient, httpPost, preUrl, nvPairList);
	}
	
	/**
	 * 翻地
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String scarify(HttpClient httpClient, HttpPost httpPost, String userId, int place) throws ClientProtocolException, IOException {
		String preUrl = "http://xn.hf.fminutes.com/api.php?mod=farmlandstatus&act=scarify&farmKey=";
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		
		return post(httpClient, httpPost, preUrl, nvPairList);
	}
	
	/**
	 * 收获或者偷菜
	 * 
	 * @param httpClient
	 * @param httpPost
	 * @param userId
	 * @param prefixUrl
	 * @param place
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String harvest(HttpClient httpClient, HttpPost httpPost, String userId, String prefixUrl, int place) throws ClientProtocolException, IOException{
		List<NameValuePair> nvPairList = new ArrayList<NameValuePair>();
		nvPairList.add(new BasicNameValuePair("place", String.valueOf(place)));
		nvPairList.add(new BasicNameValuePair("ownerId", userId));
		
		return post(httpClient, httpPost, prefixUrl, nvPairList);
	}
	
	/**
	 * 登出
	 * 
	 * @param httpClient
	 * @param httpGet
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public void logout(HttpClient httpClient, HttpGet httpGet) throws ClientProtocolException, IOException {
		String url = "http://www.renren.com/Logout.do";
		httpGet = new HttpGet(url);
		httpGet.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
		httpGet.getParams().setParameter("http.method.retry-handler", new DefaultHttpRequestRetryHandler());
		httpGet.getParams().setParameter("http.protocol.single-cookie-header", true);
		httpClient.execute(httpGet);
		httpGet.abort();
	}
}
